package com.jweb.framework.ws.soap.axiom;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultNode;
import org.apache.axiom.soap.SOAPFaultReason;
import org.apache.axiom.soap.SOAPFaultSubCode;
import org.apache.axiom.soap.SOAPFaultText;
import org.apache.axiom.soap.SOAPFaultValue;
import org.apache.axiom.soap.SOAPProcessingException;
import org.springframework.util.StringUtils;
import org.springframework.ws.soap.soap12.Soap12Fault;
import org.springframework.xml.namespace.QNameUtils;

/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：
 */
class AxiomSoap12Fault extends AxiomSoapFault implements Soap12Fault {
	
	AxiomSoap12Fault(SOAPFault axiomFault , SOAPFactory axiomFactory){
		super(axiomFault, axiomFactory);
	}
	
	public QName getFaultCode(){
		return getAxiomFault().getCode().getValue().getTextAsQName();
	}
	
	public Iterator<QName> getFaultSubcodes(){
		List<QName> subcodes = new ArrayList<QName>();
		SOAPFaultSubCode subcode = getAxiomFault().getCode().getSubCode();
		while(subcode != null){
			subcodes.add(subcode.getValue().getTextAsQName());
			subcode = subcode.getSubCode();
		}
		return subcodes.iterator();
	}
	
	public void addFaultSubcode(QName subcode) {
		SOAPFaultCode faultCode = getAxiomFault().getCode();
		SOAPFaultSubCode faultSubCode = null ;
		if(faultCode.getSubCode() == null){
			faultSubCode = getAxiomFactory().createSOAPFaultSubCode(faultCode);
		}
		else {
			faultSubCode = faultCode.getSubCode();
			while(faultSubCode.getSubCode() != null){
				faultSubCode = faultSubCode.getSubCode();
			}
		}
		SOAPFaultValue faultValue = getAxiomFactory().createSOAPFaultValue(faultSubCode);
		setValueText(subcode , faultValue);
	}
	
	private void setValueText(QName code , SOAPFaultValue faultValue) {
		String prefix = QNameUtils.getPrefix(code);
		if(StringUtils.hasLength(code.getNamespaceURI()) && StringUtils.hasLength(prefix)){
			OMNamespace namespace = getAxiomFault().findNamespaceURI(prefix);
			if(namespace == null){
				getAxiomFault().declareNamespace(code.getNamespaceURI() , prefix);
			}
		}
		else if(StringUtils.hasLength(code.getNamespaceURI())){
			OMNamespace namespace = getAxiomFault().findNamespace(code.getNamespaceURI(), null);
			if(namespace == null){
				throw new IllegalArgumentException("Could not resolve namespace of code [" + code + "]");
			}
			code = QNameUtils.createQName(code.getNamespaceURI(), code.getLocalPart(), namespace.getPrefix());
		}
		faultValue.setText(prefix + ":" + code.getLocalPart());
	}
	
	public String getFaultNode(){
		SOAPFaultNode faultNode = getAxiomFault().getNode();
		if(faultNode == null){
			return null ;
		}
		return faultNode.getNodeValue();
	}
	
	public void setFaultNode(String uri) {
		try {
			SOAPFaultNode faultNode = getAxiomFactory().createSOAPFaultNode(getAxiomFault());
			faultNode.setNodeValue(uri);
			getAxiomFault().setNode(faultNode);
		} catch (SOAPProcessingException e) {
			throw new AxiomSoapFaultException(e);
		}
	}
	
	public String getFaultStringOrReason(){
		return getFaultReasonText(Locale.getDefault());
	}
	
	public String getFaultReasonText(Locale locale) {
		SOAPFaultReason faultReason = getAxiomFault().getReason();
		String language = AxiomUtils.toLanguage(locale) ;
		SOAPFaultText faultText = faultReason.getSOAPFaultText(language);
		return faultText != null ? faultText.getText() : null ;
	}
	
	public void setFaultReasonText(Locale locale , String text) {
		SOAPFaultReason faultReason = getAxiomFault().getReason();
		String language = AxiomUtils.toLanguage(locale);
		try {
			SOAPFaultText faultText = getAxiomFactory().createSOAPFaultText(faultReason);
			faultText.setLang(language);
			faultText.setText(text);
		} catch (SOAPProcessingException e) {
			throw new AxiomSoapFaultException(e);
		}
	}
	

}
